package com.xpc.controller.qin;

import com.baomidou.mybatisplus.extension.api.R;
import com.xpc.controller.utils.SaltGeneration;
import com.xpc.pojo.Account;
import com.xpc.pojo.MyClass;
import com.xpc.pojo.Student;
import com.xpc.pojo.qin.LoginUserInfo;
import com.xpc.pojo.qin.NormalLogin;
import com.xpc.pojo.User;
import com.xpc.service.*;
import com.xpc.util.Permissions;
import lombok.Data;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;

import static com.xpc.constant.PositionStateConstant.ADMIN_POSITION_STATE_INT;

/**
 * @author Qinkuer
 * @version 1.0.0
 * @ProjectName UniversityGradeAdministrationSystem
 * @ClassName LoginController.java
 * @Description TODO 与登录相关的请求Controller
 * @createTime 2022年05月21日 18:13:00
 */
@RestController
public class LoginController {

    @Autowired
    private NormalLoginService normalLoginService;

    @Autowired
    private IAdministratorInfoService iAdministratorInfoService;

    @Autowired
    private IStudentService iStudentService;

    @Autowired
    private IMyClassService iMyClassService;

    @Autowired
    private LoginUserInfoService loginUserInfoService;

    @Autowired
    private IUserService iUserService;
    @Autowired
    private IAccountService iAccountService;

    /**
        * @description 登录
        * @param normalLogin 包含账号和密码
        * @return  com.baomidou.mybatisplus.extension.api.R
        * @author Qinkuer
        * @Date  2022/5/21
        */
    @PostMapping("login")
    public R login(@RequestBody NormalLogin normalLogin){
        if(ObjectUtils.isEmpty(normalLogin.getAccountId())||ObjectUtils.isEmpty(normalLogin.getPassword()))
            return R.failed("账号或密码数据丢失");

        try{
            Subject subject = SecurityUtils.getSubject();
//            System.out.println(subject.isAuthenticated());
            subject.login(new UsernamePasswordToken(normalLogin.getAccountId(),normalLogin.getPassword()));
//

//            Account account = iAccountService.getById(normalLogin.getAccountId());
//            User user = iUserService.getById(account.getUserId());
//            Student classId = iStudentService.getById(account.getUserId());
//            MyClass myclass = iMyClassService.getById(classId.getClassId());
            LoginUserInfo user = loginUserInfoService.getLoginUserInfoByAccountId(normalLogin.getAccountId());

            HashMap<String, Object> userAndPermission = new HashMap<>();

            userAndPermission.put("userInfo", user);
            //区分管理员与普通用户
            if(user.getPositionState()!=ADMIN_POSITION_STATE_INT)
                userAndPermission.put("permissions",new Permissions(user.getPositionState()));

            return R.ok(userAndPermission);
        }catch (UnknownAccountException | IncorrectCredentialsException e){
            return R.failed("账号或密码错误");
        }
        catch (Exception e){
            return R.failed(e.getMessage()+"\n建议联系管理员");
        }

    }

    /**
        * @description 登出
        * @return  com.baomidou.mybatisplus.extension.api.R
        * @author Qinkuer
        * @Date  2022/5/21
        */
    @GetMapping("logout")
    public R logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return R.ok("是否登出: "+ !subject.isAuthenticated());
    }

    /**
        * @description 单纯的测试使用, 查看用户当前登录状态
        * @deprecated
        * @return  com.baomidou.mybatisplus.extension.api.R
        * @author Qinkuer
        * @Date  2022/5/21
        */
    @GetMapping("Test")
    public R testIsAuthenticated(){
        Subject subject = SecurityUtils.getSubject();
        return R.ok("认证状态: " + subject.isAuthenticated()+"账号:"+(String)subject.getPrincipal());
    }


    @PutMapping("reSetPassowrd")
    public R reSetPassword(@RequestBody ChangePassword info){
        if(ObjectUtils.isEmpty(info.getAccountId())||ObjectUtils.isEmpty(info.getNewPassword())||ObjectUtils.isEmpty(info.getOldPassword()))
            return R.failed("缺失信息:账号,或密码缺失");
        NormalLogin user = normalLoginService.getUser(info.getAccountId());
        Subject subject = SecurityUtils.getSubject();
        String principal = (String) subject.getPrincipal();
        if(user==null
//                || (!principal.equals(info.getAccountId()))  //TODO 只能自己改自己的密码
        )
            return R.failed("传入的账号错误");

        Md5Hash md5Hash2 = new Md5Hash(info.getOldPassword(),user.getSalt());

        if(!md5Hash2.toHex().equals(user.getPassword()))
            return R.failed("旧密码错误");
        String newsalt = SaltGeneration.getSalt();
        Md5Hash newpassword = new Md5Hash(info.getNewPassword(),newsalt);
        User user1 = new User();
        user1.setUserId(user.getUserId());
        user1.setPassword(newpassword.toHex());
        user1.setSalt(newsalt);
        if(iUserService.saveOrUpdate(user1))
            return R.ok("密码修改成功");
        return R.failed("密码修改失败,与数据库有关");
    }


}

@Data
class ChangePassword{
    private String accountId;
    private String oldPassword;
    private String newPassword;
}
